<template>
    <div>
    <el-form  ref="form"  label-width="80px" :inline="false"  >
        <el-form-item label="SPU名称">
            <el-input placeholder="请输入SPU名称" v-model="spuParams.spuName" ></el-input>
        </el-form-item>
        <el-form-item label="SPU品牌">
            <el-select  placeholder="请选择" clearable filterable v-model="spuParams.tmId" >
                <el-option :label="trademark.tmName" :value="trademark.id" v-for="(trademark,index) in allTradeMarkArr"></el-option>
            </el-select>    
        </el-form-item>
        <el-form-item label="SPU描述">
            <el-input placeholder="请输入SPU描述"  type="textarea" v-model="spuParams.description" ></el-input>
        </el-form-item>
        <el-form-item label="SPU图片">
            <el-upload
              :file-list="imgListArr"
              action="/api/admin/product/fileUpload"
              list-type="picture-card"
              :on-preview="handlePictureCardPreview"
              :on-remove="handleRemove"
            >
              <el-icon><Plus /></el-icon>
            </el-upload>
      
            <el-dialog v-model="dialogVisible">
              <img w-full :src="dialogImageUrl" alt="Preview Image"  style="width: 400px; height: 400px; margin: 0 auto; display: block" />
            </el-dialog>
          </el-form-item>
          <el-form-item label="销售属性">
            <el-select :placeholder=" unSelectSaleAttr.length>0 ? `你还有${unSelectSaleAttr.length}未选择`:`你没得选了`" v-model="unSaleAttrIdAndName" >
              <el-option :key="select.id" :label="select.name" :value="`${select.id}:${select.name}`" v-for="(select,index) in unSelectSaleAttr" ></el-option>
            </el-select>
            <el-button
              style="margin-left: 10px"
              type="primary"
              size="default"
              :icon="Plus"
              @click="addSaleAttr"
              :disabled="!unSaleAttrIdAndName"
              >添加销售属性值</el-button
            >
            <!-- 展示属性与属性值的地方 -->
            <el-table border stripe style="margin: 10px 0px" :data="spuHasSaleAttrArr" >
              <el-table-column
                label="序号"
                type="index"
                align="center"
                width="80"
              ></el-table-column>
              <el-table-column label="属性名" width="120" prop="saleAttrName"></el-table-column>
              <el-table-column label="属性值名称列表" >
                <template #="{row,$index}">
                  <el-tag type="success" style="margin:2px 5px ;" v-for="(saleValue,index) in row.spuSaleAttrValueList" :key="saleValue.id" class="mx-1" closable @close="row.spuSaleAttrValueList.splice(index,1)" >{{saleValue.saleAttrValueName}}</el-tag>
                  <!-- button与input的切换:编辑模式与查看模式 -->
                  <el-input   v-model="row.inputValue" v-if="row.flag" style="width:100px" placeholder="请你输入属性值" size="small" clearable @blur="toLook(row)" ></el-input>
                  <el-button v-else type="primary" size="small" @click="toEdit(row)" :icon="Plus"></el-button>
                  
                  
                </template>
              </el-table-column>
              <el-table-column label="操作" width="120"></el-table-column>
            </el-table>
      
            <el-button type="primary" size="default" @click="save">保存</el-button>
            <el-button size="default" @click="cancel">取消</el-button>
          </el-form-item>
    </el-form>
    
    </div>
</template>

<script setup lang="ts">
 //引入组合式API|icon图标|数据类型
import { ref ,computed} from "vue";
import { Plus } from "@element-plus/icons-vue";
import type { UploadProps, UploadUserFile } from "element-plus";
import { ElMessage } from "element-plus";
//引入请求函数
import {reqAllaTradeMark,reqAllSaleAttr,reqImgList,reqSpuHasSaleAttr} from '@/api/product/spu/spu'   

//已有SPU下的全部品牌数据
let allTradeMarkArr = ref([]);
//获取已有SPU下照片墙的数据
let imgListArr = ref([]);
//获取已有SPU，拥有销售属性
let spuHasSaleAttrArr = ref([]);
//获取全部销售属性[不管任何SPU销售属性最多三个]--基础属性 (id,name)
let allSaleAttrArr = ref([]);

// 定义将来添加或修改SPU需要携带给服务器的参数
let spuParams=ref({})
// 收集SPU还未选择销售属性ID与名字   与下拉列表双向绑定,初始值为空,下拉框选择哪个option,就会收集到哪个option内容
let unSaleAttrIdAndName = ref('')


//照片墙相关的代码
//存储预览图片地址
const dialogImageUrl = ref("");
//控制对话框显示与隐藏
const dialogVisible = ref(false);

//删除图片回调
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles);
};
//预览回调
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

// 定义一个方法,供父组件使用,父组件点击修改按钮调用此方法
// 发请求获取当前spu数据
const initHasSpuData = async (row)=>{
 //父组件:传递过来已有SPU信息存储
 spuParams.value=row
    // 发请求
    // 获取品牌数据
    let sp1= reqAllaTradeMark()
    // 获取已有的照片墙的数据
    let sp2 = reqImgList(row.id)
    // 获取当前SPU已有的销售属性
    let sp3 = reqSpuHasSaleAttr(row.id)
    // 获取全部销售属性
    let sp4 = reqAllSaleAttr()
    // 获取全部服务器返回数据
    let result = await Promise.all([sp1,sp2,sp3,sp4])
    console.log(result);
    
    // 存储数据
      //存储全部品牌
   allTradeMarkArr.value = result[0];
   //存储照片墙的数据   因为key值不一样,需要对数据进行处理
   imgListArr.value = result[1].map((item)=>({
       name:item.imgName,
       url:item.imgUrl
   }));
   //存储已有销售属性
   spuHasSaleAttrArr.value = result[2];
   //获取全部销售属性
   allSaleAttrArr.value = result[3];

}

// 计算当前SPU,还没有选择的销售属性  filter过滤  依赖属性,当计算依赖的数据进行变化时,则会重新进行计算
const unSelectSaleAttr = computed (()=>{
  let result = allSaleAttrArr.value.filter((item)=>{
       return spuHasSaleAttrArr.value.every((item1)=>{
              return item.name!=item1.saleAttrName
       })
  })
return result

})

// 点击添加销售属性按钮的回调
const addSaleAttr = ()=>{
  // 解构出新增的销售属性ID与名字
  const [baseSaleAttrId,saleAttrName] = unSaleAttrIdAndName.value.split(':')
  // 服务器需要销售属性对象
  let newSaleAtrr = {baseSaleAttrId,saleAttrName,spuSaleAttrValueList:[]}
  // 向spu已有的数组中追加新增的销售属性
  spuHasSaleAttrArr.value.push(newSaleAtrr)
  // 清空下拉框数据
  unSaleAttrIdAndName.value= ""
}


//点击+按钮变为编辑模式的事件回调
const toEdit = (row)=>{
  //  动态追加flag属性--动态添加的属性也是响应式的
  row.flag = true
  // 收集销售属性值
  row.inputValue = ''

}

// 表单元素失去焦点的事件回调,变为编辑模式
const toLook = (row)=>{
  if(row.inputValue.trim()==''){
    ElMessage({
      type: "error",
      message: "属性值不能为空",
    });
    return
  }

  // 重名
  let repeat = row.spuSaleAttrValueList.find((item)=>{
    // itme 已有的销售属性对象            row.inputValue:新增的属性值名称
       return item.saleAttrValueName ===row.inputValue
  })

  if(repeat){
    ElMessage({
      type: "error",
      message: "属性值名称不能重复",
    });
  // 清空最新收集同名属性值
    row.inputValue = ''
    // 显示button
    row.flag = false;
    return;
  }
  // 显示button
  row.flag = false;
  // 新增属性值
  let newSaleattrVal = {
    baseSaleAttrId:row.baseSaleAttrId,
    saleAttrValueName:row.inputValue
  }
  // 追加到当前销售属性值数组中
  row.spuSaleAttrValueList.push(newSaleattrVal)
  // 清空最新收集同名属性值
  row.inputValue = ''
}

// 保存按钮的回调
const save = async ()=>{
  // 整理发请求带给服务器的参数
    spuParams.value.spuImageList = imgListArr.value.map((item)=>{
      return {
        imgName:item.name,
        imgUrl:(item.response && item.response.data) || item.url
      }
    })
    
    // 整理销售属性的参数
    spuParams.value.spuSaleAttrList  = spuHasSaleAttrArr.value
    // 发请求
    try {
      await reqAddOrUpdateSpu(spuParams.value)
      ElMessage({
      type: "success",
      message: spuParams.value.id ? "修改成功" : "添加成功",
    });
    // 触发自定义事件
    emit('changeScene',{
      screen:0,
      flag:spuParams.value.id?'update' :'add'
    })
    // 清空数据
    resetData()
    } catch (error) {
      ElMessage({
      type: "error",
      message: spuParams.value.id ? "修改失败" : "添加失败",
    });
    }
}

// 取消按钮的回调
const cancel = ()=>{
   emit('changeScene',{
      screen:0,
      flag:spuParams.value.id?'update' :'add'
   })
  //  清空数据
   resetData()
}

//清空数据
const resetData = () => {
  spuParams.value = {};
  imgListArr.value = [];
  spuHasSaleAttrArr.value = [];
};

// 点击父组件中添加SPU的时候,当前子组件发请求.获取全部品牌,获取全部销售属性
const initAddSpu = async (c3id:number|string)=>{
   //添加SPU追加三级分类ID
   spuParams.value.category3Id = c3id;
    // 获取品牌数据
    let sp1= reqAllaTradeMark()
 // 获取全部销售属性
 let sp4 = reqAllSaleAttr()
  let result = await Promise.all([sp1,sp4]);
  //存储全部品牌
  allTradeMarkArr.value = result[0];
  //获取全部销售属性
  allSaleAttrArr.value = result[1];
}

// 触发自定义事件
let emit = defineEmits(['changeScene'])
//对外暴露方法
defineExpose({
  initHasSpuData,
  initAddSpu
});
</script>

<style scoped>

</style>